﻿using System.Xml.Linq;
using Engine;
using Engine.Input;
using System;
using Engine.Graphics;
using System.Collections.Generic;
using XmlUtilities;
using System.IO;
using GameEntitySystem;
using TemplatesDatabase;
using Game;

namespace sprintDCmod
{
	public class SprintDCCamera : BasePerspectiveCamera
	{//该摄像机用于实现疾跑时的镜头拉远效果
		public override bool UsesMovementControls => false;

		public override bool IsEntityControlEnabled => true;

		public ComponentSprintDC m_componentSprintDC;
		public float FocalNum => m_componentSprintDC != null ? m_componentSprintDC.m_focalNum : 1f;
		public bool IsFocalControllable;
		public SprintDCCamera(GameWidget view) : base(view)
		{
			IsFocalControllable = false;
			m_componentSprintDC = view.Target.Entity.FindComponent<ComponentSprintDC>();
		}

		public override void Activate(Camera previousCamera)
		{
			SetupPerspectiveCamera(previousCamera.ViewPosition, previousCamera.ViewDirection, previousCamera.ViewUp);
		}

		public override void Update(float dt)
		{
			if (GameWidget.Target != null)
			{
				Vector3 eyePosition = GameWidget.Target.ComponentCreatureModel.EyePosition;
				var matrix = Matrix.CreateFromQuaternion(GameWidget.Target.ComponentCreatureModel.EyeRotation);
				matrix.Translation = GameWidget.Target.ComponentCreatureModel.EyePosition;
				bool faceToBlock = false;
				TerrainRaycastResult? terrainRaycastResult = m_componentSprintDC.m_componentPlayer.ComponentMiner.Raycast<TerrainRaycastResult>(new Ray3(eyePosition, m_componentSprintDC.m_componentPlayer.ComponentBody.Matrix.Forward), RaycastMode.Digging, true, false, true);
				if (terrainRaycastResult.HasValue && Vector3.Distance(terrainRaycastResult.Value.HitPoint(), eyePosition) <= 0.5f)
					faceToBlock = true;
				if (!faceToBlock)//没有面贴墙时应用相机位置偏移
					matrix.Translation += m_componentSprintDC.m_componentPlayer.ComponentBody.Matrix.Forward * 0.1f + matrix.Forward * 0.25f;
				SetupPerspectiveCamera(matrix.Translation, matrix.Forward, matrix.Up);
			}
		}

		public override Matrix ProjectionMatrix
		{
			get
			{
				if (!m_projectionMatrix.HasValue)
				{
					m_projectionMatrix = CalculateBaseProjectionMatrix(GameWidget.ViewWidget.ActualSize);
					ViewWidget viewWidget = GameWidget.ViewWidget;
					if (!viewWidget.ScalingRenderTargetSize.HasValue)
					{
						m_projectionMatrix *= CreateScaleTranslation(0.5f * viewWidget.ActualSize.X, -0.5f * viewWidget.ActualSize.Y, viewWidget.ActualSize.X / 2f, viewWidget.ActualSize.Y / 2f)
							* viewWidget.GlobalTransform * CreateScaleTranslation(2f / Display.Viewport.Width, -2f / Display.Viewport.Height, -1f, 1f);
					}
				}
				return m_projectionMatrix.Value;
			}
		}


		public new Matrix CalculateBaseProjectionMatrix(Vector2 wh)
		{
			float num = 90f;
			float num2 = 1f;
			if (SettingsManager.ViewAngleMode == ViewAngleMode.Narrow)
			{
				num2 = 0.8f;
			}
			else if (SettingsManager.ViewAngleMode == ViewAngleMode.Normal)
			{
				num2 = 0.9f;
			}
			float num22 = FocalNum * num2;
			float num3 = wh.X / wh.Y;//视野长宽比
			float num4 = MathUtils.Min(num * num3, num);//根据长宽比获取值，最大90f
			float num5 = num4 * num3;
			if (num5 < 90f)
			{
				num4 *= 90f / num5;
			}
			else if (num5 > 175f)
			{
				num4 *= 175f / num5;
			}
			//猜测，将世界坐标转换为屏幕坐标的矩阵
			return Matrix.CreatePerspectiveFieldOfView(MathUtils.DegToRad(num4 * num22), num3, 0.1f, 2048f);//参数1视野Y宽度，参数2纵横比，参数3近平面，参数4远平面
		}

		public static Matrix CreateScaleTranslation(float sx, float sy, float tx, float ty)
		{
			return new Matrix(sx, 0f, 0f, 0f, 0f, sy, 0f, 0f, 0f, 0f, 1f, 0f, tx, ty, 0f, 1f);
		}

	}

}
